package com.hziee.graduate.ticket.service.impl;

import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hziee.graduate.ticket.dao.*;
import com.hziee.graduate.ticket.dto.PageDTO;
import com.hziee.graduate.ticket.dto.R;
import com.hziee.graduate.ticket.entity.Cinema;
import com.hziee.graduate.ticket.entity.CinemaMovie;
import com.hziee.graduate.ticket.entity.Movie;
import com.hziee.graduate.ticket.service.MovieService;
import com.hziee.graduate.ticket.vo.ConditionMovieVO;
import com.hziee.graduate.ticket.vo.MovieChartVO;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;


@Service("movieService")
@Slf4j
public class MovieServiceImpl extends ServiceImpl<MovieDao, Movie> implements MovieService {

    @Resource
    private MovieDao movieDao;
    @Resource
    private CinemaDao cinemaDao;
    @Resource
    private CinemaMovieDao cinemaMovieDao;
    @Resource
    private TypeDao typeDao;
    @Resource
    private TicketsDao ticketsDao;

    @Override
    public R<Object> addMovie(Map<String, String> map) {
        return R.success();
    }

    @Override
    public R<List<Movie>> getHotMovie(String locationName) {
        log.debug("getHotMovie:热门电影所属地点:{}", locationName);
        //1. 获得本地的电影：cinema.parent.parent.name == locationName
        Set<Movie> sortMovieSet = getHotMoviesByView(locationName);
        //3. 返回前三部的电影
        ArrayList<Movie> resMovieList = new ArrayList<>(sortMovieSet);
        if(resMovieList.size() < 3) {
            return R.success(resMovieList.subList(0,resMovieList.size()));
        }else{
            return R.success(resMovieList.subList(0,3));
        }
    }

    private Set<Movie> getHotMoviesByView(String locationName) {
        List<Cinema> cinemaByRegionName = cinemaDao.getCinemaByRegionName(locationName);
        //2. 查找本地电影院的电影并去重
        Set<Movie> sortMovieSet = new TreeSet<Movie>(new Comparator<Movie>() {
            @Override
            public int compare(Movie o1, Movie o2) {
                return (int)(o2.getMovieView() - o1.getMovieView());
            }
        });
        List<Movie> movieList = new ArrayList<>();
        for (Cinema cinema : cinemaByRegionName) {
            HashMap<String, Object> map = new HashMap<>();
            map.put("cinema_id",cinema.getCinemaId());
            map.put("del_flag",0);
            List<CinemaMovie> cinemaMovies = cinemaMovieDao.selectByMap(map);

            for (CinemaMovie cinemaMovie : cinemaMovies) {
                Movie movie = movieDao.selectById(cinemaMovie.getMovieId());
                movieList.add(movie);
            }
        }
        sortMovieSet.addAll(movieList);
        return sortMovieSet;
    }

    @Override
    public R<List<Movie>> getLikeMovie(String locationName,Long userId) {
        // 1.按类型进行group并降序
        List<Integer> likeMovieType = typeDao.getLikeMovieType(userId);
        // 2.再根据类型在本地区热门电影之中进行推荐
        Set<Movie> hotMoviesByView = getHotMoviesByView(locationName);
        List<Movie> resMovieList = new ArrayList<>();
        likeMovieType.forEach((item) -> {
            for (Movie movie : hotMoviesByView) {
                if(item.equals(movie.getMovieTypeId())) { resMovieList.add(movie);break; }
            }
        });
        return R.success("获得喜爱电影成功", resMovieList);
    }

    @Override
    public R<List<Movie>> getAllMovieOrderByView(String locationName) {
        Set<Movie> hotMoviesByView = getHotMoviesByView(locationName);
        return R.success(new ArrayList<Movie>(hotMoviesByView));
    }

    @Override
    public R<List<Movie>> getScheduledMovie(String locationName, String date) {
        List<Movie> scheduledMovie = movieDao.getScheduledMovie(locationName, date);
        return R.success(scheduledMovie);
    }

    @Override
    public R<List<ConditionMovieVO>> getMovieByCondition(Map<String, String> map) {
        // Integer regionId, String date, Long movieId, Long currentPage
        //date不为空
        String date = map.get("date");
        String regionId = map.get("regionId");
        String movieId = map.get("movieId");
        String typeId = map.get("typeId");
        // currentPage一定要存在，上述字段是可有可无的
        Long currentPage = Long.parseLong(map.get("currentPage"));
        PageDTO<ConditionMovieVO> conditionPageDTO = new PageDTO<>();
        Integer pageSize = 2;
        Long start = currentPage * pageSize;

        Long movieCount = movieDao.getMovieCountByCondition(regionId, date, typeId, movieId);
        List<ConditionMovieVO> movieByCondition = movieDao.getLimitMovieByCondition(regionId, date, movieId,typeId,start,pageSize);
        Long totalPage = (long) Math.ceil(movieCount * 1.0 / pageSize);

        conditionPageDTO.setCurrentPage(currentPage);
        conditionPageDTO.setData(movieByCondition);
        conditionPageDTO.setTotalPage(totalPage);

        return R.success(conditionPageDTO);
    }

    @Override
    public R<List<Movie>> getMovieByKeyword(ArrayList<String> keywords) {
        Set<Movie> sortMovieSet = new TreeSet<Movie>(new Comparator<Movie>() {
            @Override
            public int compare(Movie o1, Movie o2) {
                return (int)(o2.getMovieView() - o1.getMovieView());
            }
        });
        for (String keyword : keywords) {
            String s = "%" + keyword + "%";
            List<Movie> movieByKeyword = movieDao.getMovieByKeyword(s);
            sortMovieSet.addAll(movieByKeyword);
        }
        ArrayList<Movie> resMovieList = new ArrayList<>(sortMovieSet);
        return R.success(resMovieList);
    }

    @Override
    public R<List<MovieChartVO>> getMovieChart(Map<String, Object> map) {
        // 需要获取数据的日期
        List<String> dates = (ArrayList<String>) map.get("dates");
        Long cinemaId = Long.parseLong(map.get("cinemaId").toString());
        List<MovieChartVO> res = new ArrayList<>();
        // 获取所有的排班电影，哪怕过去七天只排过一次班
        List<String> movieNames = movieDao.getScheduleMovieByCinemaIdForSeven(dates.get(0),dates.get(dates.size() - 1),cinemaId);
        // 获取每一天每部电影的电影票数据
        movieNames.forEach(item -> {
            MovieChartVO movieChartVO = new MovieChartVO();
            movieChartVO.setMovieName(item);
            dates.forEach(item2 -> {
                Integer num = ticketsDao.getTicketByMovieAndDate(item,item2);
                movieChartVO.getDatas().add(num);
            });
            res.add(movieChartVO);
        });
        return R.success(res);
    }


}

